//
// Created by guoshunw on 2021/2/6.

// https://gitee.com/guoshunw/dashboard/projects
// https://audio.online-convert.com/convert-to-opus
// https://github.com/xiph/ogg//

#include "memory"

#include "OggAnalyzer.h"
#include "OweOggAnalyzer.h"
#include <opus.h>
#ifndef WGS_OWN_PARSING
#include "ThirdPartLibOggAnalyzer.h"
#endif

OggAnalyzer::OggAnalyzer(const char *file) : _parsingFile(file) {
}

string OggAnalyzer::opusPacketToString(const unsigned char *op, opus_int32 len, int rate) {

    stringstream out;
//    logDebug("rate=%d", rate);
    // the sample rate could be obtained from opus header packet
    // could use opus dec decode opus frame info:
    auto bandwidth = opus_packet_get_bandwidth(op);
    const char *sBandwidth = "unknown";
    switch (bandwidth) {
        case OPUS_BANDWIDTH_NARROWBAND:
            sBandwidth = "NB";
            break;
        case OPUS_BANDWIDTH_MEDIUMBAND:
            sBandwidth = "MB";
            break;
        case OPUS_BANDWIDTH_WIDEBAND:
            sBandwidth = "WB";
            break;
        case OPUS_BANDWIDTH_SUPERWIDEBAND:
            sBandwidth = "SWB";
            break;
        case OPUS_BANDWIDTH_FULLBAND:
            sBandwidth = "FB";
            break;
        default:
            break;
    }
    out << sBandwidth;
    auto channel = opus_packet_get_nb_channels(op);
    out << " " << (1 == channel ? "mono" : "stereo");
    auto frames = opus_packet_get_nb_frames(op, len);
    out << ", " << frames << " frames in packet";

    auto samples = opus_packet_get_nb_samples(op, len, rate);
    out << ", " << samples << " samples in packet.";
    if (frames > 1) {
        auto samplesPerFrame = opus_packet_get_samples_per_frame(op, rate);
        out << " and " << samplesPerFrame << " samples per frame.";
    }
#if 0
    unsigned char toc;
    const unsigned char *frms[48];
    opus_int16 sizeOfEncapsulatedFrames[48];
    int payloadOffset;
    int c = opus_packet_parse(op, len, &toc, frms, sizeOfEncapsulatedFrames, &payloadOffset);
    out << " toc: " << hex << (uint16_t) toc << dec << ", payload offset: " << payloadOffset;
    // the frms and sizeOfEncapsulatedFrames save the maximum frames that in an opus packet.
    // that's mean the maximum frames in an opus packet is 48
    // the actual frame number is return by this function
    for (auto i = 0; i < c; ++i) {
        out << ", frame" << i << " len: " << sizeOfEncapsulatedFrames[i];
    }
    if (c != frames) {
        out << ", frames: " << c;
    }
#endif
    out << " hex dump: " << Utils::hexDump(op, len);
    return out.str();
}

OggAnalyzer::~OggAnalyzer() = default;


int testOggAnalyzer(int argc, char *argv[]) {
    // http://www.muonics.com/rfc/rfc6716.php#page13

    /**
     * lighttpd curl -kI --http1.0  https://localhost:8443/avstudy_resources/ogg/txh.opus
     * lighttpd curl -kI --http1.1  https://localhost:8443/avstudy_resources/ogg/txh.opus
     *
     * openssl x509  -noout -text -in /usr/local/etc/lighttpd/ssl/server.pem
     *
     * the following must add mytest112 host dns mapping into /etc/hosts
     * curl --cacert ~/Downloads/certificate/rootca.pem -I https://mytest112:8443/test.txt
     *
     * export SSL_CERT_FILE=/usr/local/etc/lighttpd/ssl/server.pem
     * */

    const char *inputFile = "http://localhost:8080/avstudy_resources/ogg/txh.opus";
    inputFile = "https://mytest112:8443/avstudy_resources/ogg/txh.opus";

    inputFile = "file:///Users/guoshunw/CLionProjects/avstudy/resources/ogg/txh.opus";
    inputFile = "file:../resources/ogg/txh.opus";
    inputFile = "../resources/ogg/txh.opus";
    inputFile = "../resources/ogg/thx_stereo_24k.opus";

    shared_ptr<OggAnalyzer> parser;
#ifdef WGS_OWN_PARSING
    parser = std::make_shared<OweOggAnalyzer>(inputFile);
#else
    parser = std::make_shared<ThirdPartLibOggAnalyzer>(inputFile);

#endif
//    return parser->parse();
    return parser->dumpOpusDataToPcm();
}

